<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    </style>
</head>

<body>
    <canvas id="canvas"></canvas>
</body>
<script id="ColorVS" type="x-shader/x-vertex">
    attribute vec4 a_Position;
    uniform float u_PointSize;
    uniform mat4 u_ModelM4;
    uniform mat4 u_PvM4;
    void main(){
        gl_Position = u_PvM4 * u_ModelM4 * a_Position;
        gl_PointSize = u_PointSize;
    }
</script>
<script id="ColorFS" type="x-shader/x-fragment">
    precision mediump float;
    uniform vec4 u_Color;
    void main(){
        gl_FragColor = u_Color;
    }
</script>
<script type="module">
    import { Matrix4, Vector3, Color, OrthographicCamera, PerspectiveCamera, Spherical, Euler } from '../js/three.module.js';
    import { CreateProgram, imgPromise } from '../js/Utils.js';
    import lib from '../js/ThreeLib.js';
    import CameraController from '../js/CameraController.js'
    import Poly from '../js/Poly4.js'
    import Control from '../js/Control.js'
    import Square from '../js/objs/Square.js'

    import Geo from '../js/Poly2/Geo.js'
    import Mat from '../js/Poly2/Mat.js'
    import Obj3D from '../js/Poly2/Obj3D.js'
    import Scene from '../js/Poly2/Scene.js'



    //#region gl
    const canvas = document.getElementById("canvas");
    canvas.width = window.innerWidth;
    canvas.height = window.innerHeight;

    const gl = canvas.getContext("webgl", { antialias: true, });
    console.log(gl)
    gl.enable(gl.BLEND);
    gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
    gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);//去图片描边
    gl.enable(gl.DEPTH_TEST);
    //#endregion

    const scene = new Scene({ gl: gl });
    scene.addAxisProgram();
    scene.regProgram('color', {
        program: CreateProgram(gl,
            document.querySelector('#ColorVS').innerText,
            document.querySelector('#ColorFS').innerText),
        attribs: ['a_Position'],
        uniforms: ['u_PvM4', 'u_ModelM4', 'u_PointSize', 'u_Color']
    })


    const pvM4 = new Matrix4();
    const modelM4 = new Matrix4();
    const eye = new Vector3(10, 1, 1);
    const lookAt = new Vector3(1, 1, 1);

    const camera = new PerspectiveCamera(45, canvas.width / canvas.height, 1, 20);
    const cameraController = new CameraController({
        canvas,
        camera,
        pvMatrix: pvM4,
        eye,
        lookAt,
    });


    const axis = new Obj3D().createAxis('axis');
    const axis1 = new Obj3D().createAxis('axis', [0, 1, 1, 1], 1);
    scene.add(axis);
    scene.add(axis1);

    const square = new Square(0.5);
    const [squareVertices, squareElements, squareNormals] = [
        square.vertices, square.elements, square.normals
    ];


    //#region main
    const obj01_node = new Vector3(1, 1, 1);
    let obj01 = create([obj01_node.x, obj01_node.y, obj01_node.z], null, [1, 1, 1, 1])
    scene.add(obj01);

    const rM4 = new Matrix4()
        .multiply(new Matrix4().makeRotationX(45 * Math.PI / 180))
        .multiply(new Matrix4().makeRotationZ(45 * Math.PI / 180))
    const normal = new Vector3(0, 1, 0).applyMatrix4(rM4);

    const obj01N = creareNormal(obj01_node, normal);
    scene.add(obj01N);

    // const obj02_node = new Vector3(0.6, 0.7, 0.4);
    const obj02_node = new Vector3(0.1, 0.2, 0.3);
    let obj02 = create([obj02_node.x, obj02_node.y, obj02_node.z], null, [1, 0, 1, 1])
    scene.add(obj02);


    // var modelM4_3_1 = new Matrix4(
    //     Math.cos(45 * Math.PI / 180), -Math.sin(45 * Math.PI / 180), 0, obj01_node.x,
    //     Math.sin(45 * Math.PI / 180), Math.cos(45 * Math.PI / 180), 0, obj01_node.y,
    //     0, 0, 1, obj01_node.z,
    //     0, 0, 0, 1
    // );
    // console.log(1, modelM4_3_1.elements)

    // const x = normal.clone().distanceTo(new Vector3(0, 0, 0));
    // var modelM4_3_1 = new Matrix4(
    //     1, 0, 0, obj01_node.x,
    //     0, 1, 0, obj01_node.y,
    //     0, 0, 1, obj01_node.z,
    //     0, 0, 0, 1
    // );
    // var rM4 = new Matrix4(
    //     normal.y / x, -(normal.x / x), 0, 0,
    //     (normal.x / x), normal.y / x, 0, 0,
    //     0, 0, 1, 0,
    //     0, 0, 0, 1
    // );
    // // var rM4_2 = new Matrix4().makeRotationZ(-45 * Math.PI / 180);

    // //绕Z
    // var rM4_z = new Matrix4(
    //     normal.y / x, (normal.x / x), 0, 0,
    //     -(normal.x / x), normal.y / x, 0, 0,
    //     0, 0, 1, 0,
    //     0, 0, 0, 1
    // );

    // //绕X
    // var rM4_x = new Matrix4(
    //     1, 0, 0, 0,
    //     0, normal.y / x, -(normal.z / x), 0,
    //     0, (normal.z / x), normal.y / x, 0,
    //     0, 0, 0, 1
    // );

    // //绕Y
    // var rM4_y = new Matrix4(
    //     normal.x / x, 0, (normal.z / x), 0,
    //     0, 1, 0, 0,
    //     -(normal.z / x), 0, normal.x / x, 0,
    //     0, 0, 0, 1
    // );

    // modelM4_3_1 = modelM4_3_1.clone()
    //     .multiply(rM4_z)
    //     .multiply(rM4_x)
    // modelM4_3_1 = modelM4_3_1.clone().multiply(rM4_y.clone())


    // console.log(rM4.elements, rM4_2.elements)

    //父元素中心点
    const node1 = new Vector3(1, 1, 1);
    //子元素中心点
    const node2 = new Vector3(0.2, 0.3, 0.4);

    //子元素进行绕父元素旋转操作
    node2.clone().applyMatrix4(
        new Matrix4(node1.x, node1.y, node1.z)                              //3.将子元素中心坐标相对于父元素中心坐标进行复位
            .multiply(new Matrix4().makeRotationX(45 * Math.PI / 180))      //2.开始进行旋转
            .multiply(new Matrix4(-node1.x, -node1.y, - node1.z))           //1.将子元素中心坐标相对于父元素中心坐标进行归零
    );


    // var obj03_node = obj02_node.clone().applyMatrix4(modelM4_3_1.clone().invert());//坐标归零

    // var modelM4_3_2 = new Matrix4();
    // modelM4_3_2.makeRotationZ(180 * Math.PI / 180);

    // var obj04_node = obj03_node.clone().applyMatrix4(modelM4_3_2);//进行旋转
    // var obj05_node = obj04_node.clone().applyMatrix4(modelM4_3_1) //复位

    // console.log(obj05_node)

    // let obj03 = create([obj05_node.x, obj05_node.y, obj05_node.z], null, [1, 0, 0, 1])
    // scene.add(obj03);

    //#endregion


    const v = normal.clone().sub(new Vector3()).normalize();
    console.log(v)



    let ang = 0;
    (function ani() {

        ang += 3 * 0.3;

        var curModelM4 = new Matrix4();
        curModelM4.makeRotationY(ang * Math.PI / 180);
        const mi = new Matrix4().setPosition(-obj01_node.x, -obj01_node.y, -obj01_node.z);
        const mb = new Matrix4().setPosition(obj01_node.x, obj01_node.y, obj01_node.z);
        // var obj03_node = obj02_node.clone().applyMatrix4(modelM4_3_1.clone().invert());//坐标归零
        // var obj04_node = obj03_node.clone().applyMatrix4(curModelM4);//进行旋转
        // var obj05_node = obj04_node.clone().applyMatrix4(modelM4_3_1) //复位

        var m = mb.clone()          //4.坐标复原
            .multiply(rM4)          //3.计算法线Up的位置
            .multiply(curModelM4)   //2.计算旋转后的位置
            .multiply(mi.clone());  //1.坐标坐标归零
        var obj05_node = obj02_node.clone().applyMatrix4(m);

        // obj03.geo.setData('a_Position', { array: new Float32Array([obj05_node.x, obj05_node.y, obj05_node.z]) })

        if (ang < 360) {
            // const mi = new Matrix4().setPosition(-obj01_node.x, -obj01_node.y, -obj01_node.z);
            // const mb = new Matrix4().setPosition(obj01_node.x, obj01_node.y, obj01_node.z);

            // const tempM4 = mb.clone().multiply(rM4.clone()).multiply(mi);
            var temp = create([obj05_node.x, obj05_node.y, obj05_node.z], null, [1, 1, 1, 1]);
            scene.add(temp);
        }

        draw();
        requestAnimationFrame(ani)
    })();


    function creareNormal(vertices, up) {
        var temp = vertices.clone().add(up.clone().normalize());
        var temp1 = vertices.clone();
        // var temp1 = vertices.clone().sub(up.clone().normalize());
        const geo = new Geo({
            data: {
                'a_Position': { size: 3, array: new Float32Array([temp1.x, temp1.y, temp1.z, temp.x, temp.y, temp.z]) },
            }
        });
        const mat = new Mat({
            program: 'color',
            mode: ['LINES'],
            data: {
                'u_PvM4': { type: 'uniformMatrix4fv', value: pvM4.elements },
                'u_ModelM4': { type: 'uniformMatrix4fv', value: new Matrix4().elements },
                'u_PointSize': { type: 'uniform1f', value: 10 },
                'u_Color': { type: 'uniform4fv', value: [1, 1, 1, 1] },
            },
        });
        return new Obj3D({ geo: geo, mat: mat, });
    }

    function create(vertices, elements = null, color = [Math.random(), Math.random(), Math.random(), 1], _modelM4 = new Matrix4()) {
        // const arr = [0, 0, 0, ...vertices]
        const arr = [...vertices]
        const geo = new Geo({
            data: {
                'a_Position': { size: 3, array: new Float32Array(arr) },
            }
        });
        const mat = new Mat({
            program: 'color',
            mode: ['LINES', 'POINTS'],
            data: {
                'u_PvM4': { type: 'uniformMatrix4fv', value: pvM4.elements },
                'u_ModelM4': { type: 'uniformMatrix4fv', value: _modelM4.elements },
                'u_PointSize': { type: 'uniform1f', value: 10 },
                'u_Color': { type: 'uniform4fv', value: color },
            },
        });
        if (elements != null) {
            geo.element = { array: new Uint16Array(elements) };
            mat.mode = ['TRIANGLES'];
        }
        return new Obj3D({ geo: geo, mat: mat, });
    }

    function draw() {
        scene.setUniform('u_PvM4', { value: pvM4.elements });
        scene.draw();
    }
</script>

</html>